package com.base;

import java.util.Hashtable;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class WapUtils {
	// User-Agent and Accept HTTP request headers

	private String userAgent = "";
	private String httpAccept = "";
	private String httpUAProfile = "";

	// Optional: store values for quickly accessing same info multiple times.
	// Call InitDeviceScan() to initialize these values.
	public boolean isIphone = false;
	public boolean isTierIphone = false;
	public boolean isTierRichCss = false;
	public boolean isTierGenericMobile = false;

	// Initialize some initial smartphone string variables.
	public static final String engineWebKit = "webkit";
	public static final String deviceAndroid = "android";

	public static final String deviceIphone = "iphone";
	public static final String deviceIpod = "ipod";
	public static final String deviceIpad = "ipad";
	public static final String deviceMacPpc = "macintosh"; // Used for
	// disambiguation

	public static final String deviceSymbian = "symbian";
	public static final String deviceS60 = "series60";
	public static final String deviceS70 = "series70";
	public static final String deviceS80 = "series80";
	public static final String deviceS90 = "series90";

	public static final String deviceWinPhone7 = "windows phone os 7";
	public static final String deviceWinMob = "windows ce";
	public static final String deviceWindows = "windows";
	public static final String deviceIeMob = "iemobile";
	public static final String devicePpc = "ppc"; // Stands for PocketPC
	public static final String enginePie = "wm5 pie"; // An old Windows Mobile

	public static final String deviceBB = "blackberry";
	public static final String vndRIM = "vnd.rim"; // Detectable when BB
	// devices emulate IE or
	// Firefox
	public static final String deviceBBStorm = "blackberry95"; // Storm 1 and 2
	public static final String deviceBBBold = "blackberry97"; // Bold
	public static final String deviceBBTour = "blackberry96"; // Tour
	public static final String deviceBBCurve = "blackberry89"; // Curve 2
	public static final String deviceBBTorch = "blackberry 98"; // Torch

	public static final String devicePalm = "palm";
	public static final String deviceWebOS = "webos"; // For Palm's new WebOS
	// devices
	public static final String engineBlazer = "blazer"; // Old Palm
	public static final String engineXiino = "xiino"; // Another old Palm

	public static final String deviceKindle = "kindle"; // Amazon Kindle, eInk
	// one.

	public static final String deviceNuvifone = "nuvifone"; // Garmin Nuvifone

	// Initialize variables for mobile-specific content.
	public static final String vndwap = "vnd.wap";
	public static final String wml = "wml";

	// Initialize variables for other random devices and mobile browsers.
	public static final String deviceBrew = "brew";
	public static final String deviceDanger = "danger";
	public static final String deviceHiptop = "hiptop";
	public static final String devicePlaystation = "playstation";
	public static final String deviceNintendoDs = "nitro";
	public static final String deviceNintendo = "nintendo";
	public static final String deviceWii = "wii";
	public static final String deviceXbox = "xbox";
	public static final String deviceArchos = "archos";

	public static final String engineOpera = "opera"; // Popular browser
	public static final String engineNetfront = "netfront"; // Common embedded
	// OS browser
	public static final String engineUpBrowser = "up.browser"; // common on
	// some phones
	public static final String engineOpenWeb = "openweb"; // Transcoding by
	// OpenWave server
	public static final String deviceMidp = "midp"; // a mobile Java technology
	public static final String uplink = "up.link";
	public static final String engineTelecaQ = "teleca q"; // a modern feature
	// phone browser
	public static final String devicePda = "pda"; // some devices report
	// themselves as PDAs
	public static final String mini = "mini"; // Some mobile browsers put
	// "mini" in their names.
	public static final String mobile = "mobile"; // Some mobile browsers put
	// "mobile" in their user
	// agent strings.
	public static final String mobi = "mobi"; // Some mobile browsers put
	// "mobi" in their user agent
	// strings.

	// Use Maemo, Tablet, and Linux to test for Nokia"s Internet Tablets.
	public static final String maemo = "maemo";
	public static final String maemoTablet = "tablet";
	public static final String linux = "linux";
	public static final String qtembedded = "qt embedded"; // for Sony Mylo
	public static final String mylocom2 = "com2"; // for Sony Mylo also

	// In some UserAgents, the only clue is the manufacturer.
	public static final String manuSonyEricsson = "sonyericsson";
	public static final String manuericsson = "ericsson";
	public static final String manuSamsung1 = "sec-sgh";
	public static final String manuSony = "sony";
	public static final String manuHtc = "htc"; // Popular Android and WinMo
	// manufacturer

	// In some UserAgents, the only clue is the operator.
	public static final String svcDocomo = "docomo";
	public static final String svcKddi = "kddi";
	public static final String svcVodafone = "vodafone";

	/**
	 * Initialize the userAgent and httpAccept variables
	 * 
	 * @param userAgent
	 *            the User-Agent header
	 * @param httpAccept
	 *            the Accept header
	 */
	public WapUtils(String userAgent, String httpAccept) {
		if (userAgent != null) {
			this.userAgent = userAgent.toLowerCase();
		}
		if (httpAccept != null) {
			this.httpAccept = httpAccept.toLowerCase();
		}

		// Intialize key stored values.
		initDeviceScan();
	}

	public String getHttpUAProfile() {
		return httpUAProfile;
	}

	public void setHttpUAProfile(String httpUAProfile) {
		this.httpUAProfile = httpUAProfile;
	}

	public WapUtils(String httpUAProfile) {
		if (httpUAProfile != null)
			this.httpUAProfile = httpUAProfile;
	}
	
	public WapUtils() {
	}

	/**
	 * Return the lower case HTTP_USER_AGENT
	 */
	public String getUserAgent() {
		return userAgent;
	}

	/**
	 * Return the lower case HTTP_ACCEPT
	 */
	public String getHttpAccept() {
		return httpAccept;
	}

	/**
	 * Return whether the device is an Iphone or iPod Touch
	 */
	public boolean getIsIphone() {
		return isIphone;
	}

	/**
	 * Return whether the device is in the Iphone Tier.
	 */
	public boolean getIsTierIphone() {
		return isTierIphone;
	}

	/**
	 * Return whether the device is an Iphone or iPod Touch
	 */
	public boolean getIsTierRichCss() {
		return isTierRichCss;
	}

	/**
	 * Return whether the device is an Iphone or iPod Touch
	 */
	public boolean getIsTierGenericMobile() {
		return isTierGenericMobile;
	}

	/**
	 * Initialize Key Stored Values.
	 */
	public void initDeviceScan() {
		this.isIphone = detectIphoneOrIpod();
		this.isTierIphone = detectTierIphone();
		this.isTierRichCss = detectTierRichCss();
		this.isTierGenericMobile = detectTierOtherPhones();
	}

	/**
	 * Detects if the current device is an iPhone.
	 */
	public boolean detectIphone() {
		// The iPad and iPod touch say they're an iPhone! So let's disambiguate.
		if (userAgent.indexOf(deviceIphone) != -1 && !detectIpad()
				&& !detectIpod()) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is an iPod Touch.
	 */
	public boolean detectIpod() {
		if (userAgent.indexOf(deviceIpod) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is an iPad tablet.
	 */
	public boolean detectIpad() {
		if (userAgent.indexOf(deviceIpad) != -1 && detectWebkit()) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is an iPhone or iPod Touch.
	 */
	public boolean detectIphoneOrIpod() {
		// We repeat the searches here because some iPods may report themselves
		// as an iPhone, which would be okay.
		if (userAgent.indexOf(deviceIphone) != -1
				|| userAgent.indexOf(deviceIpod) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is an Android OS-based device.
	 */
	public boolean detectAndroid() {
		if (userAgent.indexOf(deviceAndroid) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is an Android OS-based device and the
	 * browser is based on WebKit.
	 */
	public boolean detectAndroidWebKit() {
		if (detectAndroid() && detectWebkit()) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current browser is based on WebKit.
	 */
	public boolean detectWebkit() {
		if (userAgent.indexOf(engineWebKit) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current browser is the S60 Open Source Browser.
	 */
	public boolean detectS60OssBrowser() {
		// First, test for WebKit, then make sure it's either Symbian or S60.
		if (detectWebkit()
				&& (userAgent.indexOf(deviceSymbian) != -1 || userAgent
						.indexOf(deviceS60) != -1)) {
			return true;
		}
		return false;
	}

	/**
	 * 
	 * Detects if the current device is any Symbian OS-based device, including
	 * older S60, Series 70, Series 80, Series 90, and UIQ, or other browsers
	 * running on these devices.
	 */
	public boolean detectSymbianOS() {
		if (userAgent.indexOf(deviceSymbian) != -1
				|| userAgent.indexOf(deviceS60) != -1
				|| userAgent.indexOf(deviceS70) != -1
				|| userAgent.indexOf(deviceS80) != -1
				|| userAgent.indexOf(deviceS90) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current browser is a Windows Phone 7 device.
	 */
	public boolean DetectWindowsPhone7() {
		if (userAgent.indexOf(deviceWinPhone7) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current browser is a Windows Mobile device. Excludes
	 * Windows Phone 7 devices. Focuses on Windows Mobile 6.xx and earlier.
	 */
	public boolean detectWindowsMobile() {
		// Exclude new Windows Phone 7.
		if (DetectWindowsPhone7()) {
			return false;
		}
		// Most devices use 'Windows CE', but some report 'iemobile'
		// and some older ones report as 'PIE' for Pocket IE.
		// We also look for instances of HTC and Windows for many of their WinMo
		// devices.
		if (userAgent.indexOf(deviceWinMob) != -1
				|| userAgent.indexOf(deviceWinMob) != -1
				|| userAgent.indexOf(deviceIeMob) != -1
				|| userAgent.indexOf(enginePie) != -1
				|| (userAgent.indexOf(manuHtc) != -1 && userAgent
						.indexOf(deviceWindows) != -1)
				|| (detectWapWml() && userAgent.indexOf(deviceWindows) != -1)) {
			return true;
		}

		// Test for Windows Mobile PPC but not old Macintosh PowerPC.
		if (userAgent.indexOf(devicePpc) != -1
				&& !(userAgent.indexOf(deviceMacPpc) != -1))
			return true;

		return false;
	}

	/**
	 * Detects if the current browser is a BlackBerry of some sort.
	 */
	public boolean detectBlackBerry() {
		if (userAgent.indexOf(deviceBB) != -1
				|| httpAccept.indexOf(vndRIM) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current browser is a BlackBerry device AND uses a
	 * WebKit-based browser. These are signatures for the new BlackBerry OS 6.
	 * Examples: Torch
	 */
	public boolean DetectBlackBerryWebKit() {
		if (userAgent.indexOf(deviceBB) != -1
				&& userAgent.indexOf(engineWebKit) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current browser is a BlackBerry Touch device, such as the
	 * Storm or Torch
	 */
	public boolean detectBlackBerryTouch() {
		if (userAgent.indexOf(deviceBBStorm) != -1
				|| userAgent.indexOf(deviceBBTorch) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current browser is a BlackBerry device AND has a more
	 * capable recent browser. Examples, Storm, Bold, Tour, Curve2 Excludes the
	 * new BlackBerry OS 6 browser!!
	 */
	public boolean detectBlackBerryHigh() {
		// Disambiguate for BlackBerry OS 6 (WebKit) browser
		if (DetectBlackBerryWebKit())
			return false;
		if (detectBlackBerry()) {
			if (detectBlackBerryTouch()
					|| userAgent.indexOf(deviceBBBold) != -1
					|| userAgent.indexOf(deviceBBTour) != -1
					|| userAgent.indexOf(deviceBBCurve) != -1) {
				return true;
			} else {
				return false;
			}
		} else {
			return false;
		}
	}

	/**
	 * Detects if the current browser is a BlackBerry device AND has an older,
	 * less capable browser. Examples: Pearl, 8800, Curve1
	 */
	public boolean detectBlackBerryLow() {
		if (detectBlackBerry()) {
			// Assume that if it's not in the High tier, then it's Low
			if (detectBlackBerryHigh()) {
				return false;
			} else {
				return true;
			}
		} else {
			return false;
		}
	}

	/**
	 * Detects if the current browser is on a PalmOS device.
	 */
	public boolean detectPalmOS() {
		// Most devices nowadays report as 'Palm', but some older ones reported
		// as Blazer or Xiino.
		if (userAgent.indexOf(devicePalm) != -1
				|| userAgent.indexOf(engineBlazer) != -1
				|| userAgent.indexOf(engineXiino) != -1) {
			// Make sure it's not WebOS first
			if (detectPalmWebOS()) {
				return false;
			} else {
				return true;
			}
		}
		return false;
	}

	/**
	 * Detects if the current browser is on a Palm device running the new WebOS.
	 */
	public boolean detectPalmWebOS() {
		if (userAgent.indexOf(deviceWebOS) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current browser is a Garmin Nuvifone.
	 */
	public boolean detectGarminNuvifone() {
		if (userAgent.indexOf(deviceNuvifone) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Check to see whether the device is any device in the 'smartphone'
	 * category.
	 */
	public boolean detectSmartphone() {
		return (detectIphoneOrIpod() || detectS60OssBrowser()
				|| detectSymbianOS() || detectAndroid()
				|| detectWindowsMobile() || DetectWindowsPhone7()
				|| detectBlackBerry() || detectPalmWebOS() || detectPalmOS() || detectGarminNuvifone());
	}

	/**
	 * Detects whether the device is a Brew-powered device.
	 */
	public boolean detectBrewDevice() {
		if (userAgent.indexOf(deviceBrew) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects the Danger Hiptop device.
	 */
	public boolean detectDangerHiptop() {
		if (userAgent.indexOf(deviceDanger) != -1
				|| userAgent.indexOf(deviceHiptop) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects Opera Mobile or Opera Mini.
	 */
	public boolean detectOperaMobile() {
		if (userAgent.indexOf(engineOpera) != -1
				&& (userAgent.indexOf(mini) != -1 || userAgent.indexOf(mobi) != -1)) {
			return true;
		}
		return false;
	}

	/**
	 * Detects whether the device supports WAP or WML.
	 */
	public boolean detectWapWml() {
		if (httpAccept.indexOf(vndwap) != -1 || httpAccept.indexOf(wml) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is an Amazon Kindle.
	 */
	public boolean detectKindle() {
		if (userAgent.indexOf(deviceKindle) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * The quick way to detect for a mobile device. Will probably detect most
	 * recent/current mid-tier Feature Phones as well as smartphone-class
	 * devices. Excludes Apple iPads.
	 */
	public boolean detectMobileQuick() {
		// Let's say no if it's an iPad, which contains 'mobile' in its user
		// agent
		if (detectIpad()) {
			return false;
		}
		// Most mobile browsing is done on smartphones
		if (detectSmartphone()) {
			return true;
		}

		if (detectWapWml()) {
			return true;
		}
		if (detectBrewDevice()) {
			return true;
		}
		if (detectOperaMobile()) {
			return true;
		}

		if (userAgent.indexOf(engineNetfront) != -1) {
			return true;
		}
		if (userAgent.indexOf(engineUpBrowser) != -1) {
			return true;
		}
		if (userAgent.indexOf(engineOpenWeb) != -1) {
			return true;
		}

		if (detectDangerHiptop()) {
			return true;
		}

		if (detectMidpCapable()) {
			return true;
		}

		if (detectMaemoTablet()) {
			return true;
		}
		if (detectArchos()) {
			return true;
		}

		if (userAgent.indexOf(devicePda) != -1) {
			return true;
		}
		if (userAgent.indexOf(mobile) != -1) {
			return true;
		}

		return false;
	}

	/**
	 * Detects if the current device is a Sony Playstation.
	 */
	public boolean detectSonyPlaystation() {
		if (userAgent.indexOf(devicePlaystation) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is a Nintendo game device.
	 */
	public boolean detectNintendo() {
		if (userAgent.indexOf(deviceNintendo) != -1
				|| userAgent.indexOf(deviceWii) != -1
				|| userAgent.indexOf(deviceNintendoDs) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is a Microsoft Xbox.
	 */
	public boolean detectXbox() {
		if (userAgent.indexOf(deviceXbox) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is an Internet-capable game console.
	 */
	public boolean detectGameConsole() {
		if (detectSonyPlaystation() || detectNintendo() || detectXbox()) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device supports MIDP, a mobile Java technology.
	 */
	public boolean detectMidpCapable() {
		if (userAgent.indexOf(deviceMidp) != -1
				|| httpAccept.indexOf(deviceMidp) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is on one of the Maemo-based Nokia Internet
	 * Tablets.
	 */
	public boolean detectMaemoTablet() {
		if (userAgent.indexOf(maemo) != -1) {
			return true;
		} else if (userAgent.indexOf(maemoTablet) != -1
				&& userAgent.indexOf(linux) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current device is an Archos media player/Internet tablet.
	 */
	public boolean detectArchos() {
		if (userAgent.indexOf(deviceArchos) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * Detects if the current browser is a Sony Mylo device.
	 */
	public boolean detectSonyMylo() {
		if (userAgent.indexOf(manuSony) != -1
				&& (userAgent.indexOf(qtembedded) != -1 || userAgent
						.indexOf(mylocom2) != -1)) {
			return true;
		}
		return false;
	}

	/**
	 * The longer and more thorough way to detect for a mobile device. Will
	 * probably detect most feature phones, smartphone-class devices, Internet
	 * Tablets, Internet-enabled game consoles, etc. This ought to catch a lot
	 * of the more obscure and older devices, also -- but no promises on
	 * thoroughness!
	 */
	public boolean detectMobileLong() {
		if (detectMobileQuick() || detectGameConsole() || detectSonyMylo()) {
			return true;
		}

		// detect older phones from certain manufacturers and operators.
		if (userAgent.indexOf(uplink) != -1) {
			return true;
		}
		if (userAgent.indexOf(manuSonyEricsson) != -1) {
			return true;
		}
		if (userAgent.indexOf(manuericsson) != -1) {
			return true;
		}
		if (userAgent.indexOf(manuSamsung1) != -1) {
			return true;
		}

		if (userAgent.indexOf(svcDocomo) != -1) {
			return true;
		}
		if (userAgent.indexOf(svcKddi) != -1) {
			return true;
		}
		if (userAgent.indexOf(svcVodafone) != -1) {
			return true;
		}

		return false;
	}

	// *****************************
	// For Mobile Web Site Design
	// *****************************
	/**
	 * The quick way to detect for a tier of devices. This method detects for
	 * devices which can display iPhone-optimized web content. Includes iPhone,
	 * iPod Touch, Android, Palm WebOS, etc.
	 */
	public boolean detectTierIphone() {
		if (detectIphoneOrIpod() || detectAndroid() || detectAndroidWebKit()
				|| DetectWindowsPhone7() || DetectBlackBerryWebKit()
				|| detectPalmWebOS() || detectGarminNuvifone()
				|| detectMaemoTablet()) {
			return true;
		}
		return false;
	}

	/**
	 * The quick way to detect for a tier of devices. This method detects for
	 * devices which are likely to be capable of viewing CSS content optimized
	 * for the iPhone, but may not necessarily support JavaScript. Excludes all
	 * iPhone Tier devices.
	 */
	public boolean detectTierRichCss() {
		// The following devices are explicitly ok.
		// Note: 'High' BlackBerry devices ONLY
		if (detectMobileQuick()
				&& (detectWebkit() || detectS60OssBrowser()
						|| detectBlackBerryHigh() || detectWindowsMobile() || userAgent
						.indexOf(engineTelecaQ) != -1)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * The quick way to detect for a tier of devices. This method detects for
	 * all other types of phones, but excludes the iPhone and RichCSS Tier
	 * devices.
	 */
	public boolean detectTierOtherPhones() {
		if (detectMobileQuick() && (!detectTierIphone())
				&& (!detectTierRichCss())) {
			return true;
		}
		return false;
	}

	/**
	 * Doc thong tin trong User Agent Profile URL yahoo = new URL(sWapProfile);
	 * URLConnection yc = yahoo.openConnection(); BufferedReader in = new
	 * BufferedReader( new InputStreamReader(yc.getInputStream())); String
	 * inputLine;
	 */
	private Document document = null;
	private Hashtable<String, String> hardwarePlatformProfile = null;
	private Hashtable<String, String> softwarePlatformProfile = null;
	private Hashtable<String, String> networkCharacteristics = null;
	private Hashtable<String, String> browserUA = null;
	private Hashtable<String, String> wapCharacteristics = null;
	private Hashtable<String, String> pushCharacteristics = null;
	private Hashtable<String, String> mmsCharacteristics = null;
	private Hashtable<String, String> streaming = null;
	
	
	public Hashtable<String, String> getHardwarePlatformProfile() { return hardwarePlatformProfile; }
	public Hashtable<String, String> getSoftwarePlatformProfile() { return softwarePlatformProfile; }
	public Hashtable<String, String> getNetworkCharacteristics() { return networkCharacteristics; }
	public Hashtable<String, String> getBrowserUA() { return browserUA; }
	public Hashtable<String, String> getWapCharacteristics() { return wapCharacteristics; }
	public Hashtable<String, String> getPushCharacteristics() { return pushCharacteristics; }
	public Hashtable<String, String> getMmsCharacteristics() { return mmsCharacteristics; }
	public Hashtable<String, String> getStreaming() { return streaming; }
	
	public boolean readProfile() {
		boolean result = false;
		try {
			System.out.println("Read profile " + httpUAProfile);
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
		    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
		    document = dBuilder.parse(httpUAProfile);
		    document.getDocumentElement().normalize();
			System.out.println("The document: " + document.getDocumentElement().getNodeName());

			// Get Platform Profile
			readPlatformProfile();
			
		} catch (Exception e) {
		}
		return result;
	}
	
	private Hashtable<String, String> readFlatform(NodeList nList, int docIndex) {
		Hashtable<String, String> hashtable = new Hashtable<String, String>();
		if (nList != null) {
			Node nNode = nList.item(docIndex);
			if (nNode.getNodeType() == Node.ELEMENT_NODE) {
				Element eElement = (Element) nNode;
				nList = eElement.getChildNodes().item(1).getChildNodes();
				for (int temp = 0; temp < nList.getLength(); temp++) {
					nNode = nList.item(temp);
					if (nNode.getNodeType() == Node.ELEMENT_NODE) {
						eElement = (Element) nNode;
						if ("rdf:type".equalsIgnoreCase(eElement.getNodeName())) continue;
						String sContent = eElement.getTextContent();
						if (sContent != null) {
							sContent = sContent.replaceAll(" ", "").replaceAll("\r", "\n").replaceAll("\n\n", "").replaceAll("\t", "");
							hashtable.put(eElement.getNodeName(),sContent.trim());
						}
					}
				}
			}
		}
		return hashtable;
	}
	
	/**
	 * Get cac component trong file UAProfile
	 */
	public void readPlatformProfile() {
		hardwarePlatformProfile = null;
		try {
			NodeList nList = document.getElementsByTagName("prf:component");
			for (int i = 0; i < nList.getLength(); i++) {
				Node desNode = nList.item(i).getChildNodes().item(1);
				String rdfID = desNode.getAttributes().item(0).getNodeValue();
				if ("HardwarePlatform".equalsIgnoreCase(rdfID)) hardwarePlatformProfile = readFlatform(nList, i);
				else if ("SoftwarePlatform".equalsIgnoreCase(rdfID)) softwarePlatformProfile = readFlatform(nList, i);
				else if ("NetworkCharacteristics".equalsIgnoreCase(rdfID)) networkCharacteristics = readFlatform(nList, i);
				else if ("BrowserUA".equalsIgnoreCase(rdfID)) browserUA = readFlatform(nList, i);
				else if ("WapCharacteristics".equalsIgnoreCase(rdfID)) wapCharacteristics = readFlatform(nList, i);
				else if ("PushCharacteristics".equalsIgnoreCase(rdfID)) pushCharacteristics = readFlatform(nList, i);
				else if ("MmsCharacteristics".equalsIgnoreCase(rdfID)) mmsCharacteristics = readFlatform(nList, i);
				else if ("Streaming".equalsIgnoreCase(rdfID)) streaming = readFlatform(nList, i);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public boolean checkValue(Hashtable<String, String> map, String key, String valueCompare) {
		boolean result = false;
		if (map != null && !map.isEmpty()) {
			String value = map.get(key);
			if (value != null && !"".equals(value.trim()) && valueCompare != null && !"".equals(valueCompare.trim())) {
				result = (value.toLowerCase()+"\n").indexOf(valueCompare.toLowerCase()+"\n") >= 0; 
			}
		}
		return result;
	}
	
	/**
	 * Xac dinh UserAgent Profile. <br>Chu y: Khong phai may nao cung ho tro cung cap cac thong tin nay.
	 */
	public String detectUAProrile(HttpServletRequest request) {
		String sWapProfile = request.getHeader("x-wap-profile");
		if (sWapProfile == null || "".equals(sWapProfile.trim())) {
			sWapProfile = request.getHeader("profile");
			if (sWapProfile == null || "".equals(sWapProfile.trim())) {
				sWapProfile = request.getHeader("opt");
				if (sWapProfile != null && !"".equals(sWapProfile.trim())) {
					sWapProfile = sWapProfile.toLowerCase();
					int nsIdx = sWapProfile.indexOf("ns=");
					if (nsIdx > 0) {
						sWapProfile = sWapProfile.substring(nsIdx + 3);
						sWapProfile = request.getHeader(sWapProfile + "-profile");
					}
				}
			}
		}
		return sWapProfile;
	}
	
	public static void main(String[] args) {
		String uaProfile = //"http://wap.sonyericsson.com/UAprof/A260R101.xml";
				//"http://device.sprintpcs.com/Samsung/SPH-A660/XA28.rdf";
				//"http://device.sprintpcs.com/Samsung/SPH-A920/YK12.rdf";
				"http://nds1.nds.nokia.com/uaprof/N6230ir200.xml";
		WapUtils wapUtils = new WapUtils(uaProfile);
		wapUtils.readProfile();
		Hashtable<String, String> h1 = wapUtils.getHardwarePlatformProfile();
		if (h1 != null) {
			System.out.println(
				  "Vendor: " + h1.get("prf:Vendor") 
				+ ", Model: " + h1.get("prf:Model")
				+ ", ScreenSize: " + h1.get("prf:ScreenSize")
				);
			String screenSize = h1.get("prf:ScreenSize");
			System.out.println(screenSize);
		}
		
	}
}
